class SnakeTime{
	constructor(options){
		const {canvasId,width,height,nodes,nodesep,ranksep,padding,nodeWidth,nodeHeight} = options;
		this.canvasId = canvasId;
		this.canvas = null;
		this.width = width;
		this.height = height;
		this.nodes = nodes;
		this.edges = [];
		this.nodesep = nodesep || 200;//水平节点之间距离，默认300
		this.ranksep = ranksep || 150;//垂直节点之间距离，默认150
		this.padding = padding || [50,50,50,50];//画布内边距：上、右、下，左
		this.nodeWidth = nodeWidth || 100;//节点宽，默认100
		this.nodeHeight = nodeHeight || 30;//节点高，默认30
	}
	//初始化
	init(){
		this.createLayout();
		this.edges = this.getEdges();
		this.canvas = this.createCanvas();
		this.initNode();
		this.initEdge();
		
		console.log(this.nodes,this.edges)
	}
	//节点排序
	nodeSort(){
		
	}
	initNode(){
		this.nodes.forEach((item,index,list)=>{
			const {id,name,px,py} = item;
			const node = this.createNode(id,name,px,py);
			item.model = node;
			this.canvas.add(node);
		});
	}
	initEdge(){
		this.edges.forEach(item=>{
			const {id,startPoint,endPoint} = item;
			const edge = this.createEdge(id,startPoint,endPoint);
			this.canvas.add(edge);
			item.model = edge;
			item.startPoint = startPoint;
			item.endPoint = endPoint;
			this.canvas.sendToBack(edge); //边置底
		});
	}
	//通过布局后的节点初始化边
	getEdges(){
		const len = this.nodes.length;
		const edges = [];
		this.nodes.forEach((item,index,list)=>{
			if(index + 1 <= len -1){
				const startPoint = item;//起点
				const endPoint = list[index + 1];//终点
				const edge = {
					id:startPoint.id + ">>" + endPoint.id,
					startPoint,
					endPoint,
				};
				edges.push(edge);
			}
		});
		return edges;
	}
	//画板
	createCanvas(){
		return new fabric.Canvas(this.canvasId,{
			width:this.width,
			height:this.height,
			hoverCursor:'default',//鼠标移上去默认形状
			perPixelTargetFind: true, //选中的时候以图形的实际大小来选择而不是以边框来选择
			selection:false,//是否可选中
			//skipTargetFind:true,//为true的话选中的target将为null 
		});
	}
	//节点
	createNode(id = new Date().getTime(),name = "未知",left,top){
		const rect = new fabric.Rect({
			width:this.nodeWidth,
			height:this.nodeHeight,
			fill:'red',
			radus:10,
			originX:'center',
			originY:'center',
			rx: 15,
			ry: 15,
		});
		const text = new fabric.Textbox(name,{
			fontSize:12,
			fill:"white",
			originX:'center',
			originY:'center',
		});
		return new fabric.Group([rect,text],{
			id,
			left,
			top,
			lockMovementX: true, 
			lockMovementY: true,
			selectable:false,
		});
	}
	//线
	createEdge(id,startPoint,endPoint){
		const start = {
			x:startPoint.x,
			y:startPoint.y
		};
		const end = {
			x:endPoint.x,
			y:endPoint.y,
		};
		let position = [start,end];
		if(startPoint.isOdd && !endPoint.isOdd){
			position = [
				start,
				{
					x:this.width - this.padding[1],
					y:start.y
				},
				{
					x:this.width - this.padding[1],
					y:end.y,
				},
				end
			];
		}else if(!startPoint.isOdd && endPoint.isOdd){
			position = [
				start,
				{
					x:this.padding[3],
					y:start.y,
				},
				{
					x:this.padding[3],
					y:end.y,
				},
				end
			];
		}
		return new fabric.Polyline(position,{
			id,
			fill: 'white',//填充颜色
			stroke: '#5E2300',//笔触颜色
		});
	}
	//节点动画
	nodeAnimate(canvas,obj,position){
		const [x,y] = position;
		obj.animate("left",x,{
			duration: 1000,
			onChange: canvas.renderAll.bind(canvas),
			onComplete: function() {
				console.log("播放结束!");
			},
			easing: fabric.util.ease.easeInCubic
		});
		obj.animate("top",y,{
			duration: 1000,
			onChange: canvas.renderAll.bind(canvas),
			onComplete: function() {
				console.log("播放结束!");
			},
			easing: fabric.util.ease.easeInCubic
		});
	}
	//边动画
	edgeAnimate(canvas,obj,position){
		obj.animate();
	}
	//布局
	createLayout(){
		const [startY,endX,endY,startX] = this.padding;
		const width = this.width - startX - endX - this.nodeWidth;
		const count = parseInt(width / this.nodesep) + 1;
		const space = (width - this.nodesep * (count - 1))/2 + this.nodeWidth / 2;//两边留白
		this.nodes.forEach((item,index,list)=>{
			item.index = index;
			item.row = parseInt(index / count) + 1;
			item.col = index % count + 1;
			item.isOdd = (item.row % 2) === 1;//是否奇数行
			if(item.isOdd){
				item.x = startX + space + this.nodesep * (item.col - 1);
			}else{
				item.x = startX + space + this.nodesep * (count - item.col);
			}
			item.y = startY + this.ranksep * (item.row - 1);
			item.px = item.x - this.nodeWidth/2;
			item.py = item.y - this.nodeHeight/2;
			//x,y是节点中心坐标，px,py是节点left，top坐标
		});
	}
}